fix(flows): replace GET /flows/exists with POST to support URI-unsaflow names#264
fix(flows): replace GET /flows/exists with POST to support URI-unsaflow names#264Jayant-kernel wants to merge 9 commits intoopenml:mainfrom
Conversation
… flow names
The GET /flows/exists/{name}/{external_version} endpoint broke for flows
with URI-unsafe characters in their names (e.g. sklearn flows with
parentheses). Replaced with POST /flows/exists accepting name and
external_version in the request body, resolving issue openml#166.
Closes openml#166
for more information, see https://pre-commit.ci
WalkthroughThe flow existence check was changed from a GET path to POST /flows/exists and now accepts a new Pydantic model FlowExistsBody (fields 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- Removing the
GET /flows/exists/{name}/{external_version}route entirely may break existing Python API consumers that construct URLs directly; consider keeping the GET route as a thin wrapper around the new POST handler for a deprecation period. - Since the request model is just a simple name/version pair, you might want to reuse or place
FlowExistsBodyin a shared schemas module so it can be consistently referenced by any future endpoints that need the same shape.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Removing the `GET /flows/exists/{name}/{external_version}` route entirely may break existing Python API consumers that construct URLs directly; consider keeping the GET route as a thin wrapper around the new POST handler for a deprecation period.
- Since the request model is just a simple name/version pair, you might want to reuse or place `FlowExistsBody` in a shared schemas module so it can be consistently referenced by any future endpoints that need the same shape.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
@PGijsbers |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/routers/openml/flows.py (1)
5-18:⚠️ Potential issue | 🟡 MinorReject empty strings in the new request body.
The old path route could not match empty
nameorexternal_version, butFlowExistsBodyaccepts""for both fields via plain Pydanticstrtype. This widens the contract and turns requests with empty strings into a DB lookup that returns no match, resulting in a 404 instead of early validation.Suggested fix
-from pydantic import BaseModel +from pydantic import BaseModel, Field ... class FlowExistsBody(BaseModel): - name: str - external_version: str + name: str = Field(min_length=1) + external_version: str = Field(min_length=1)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/routers/openml/flows.py` around lines 5 - 18, FlowExistsBody currently allows empty strings for name and external_version because both are plain str; change the model to reject empty values by specifying non-empty constraints (e.g., use pydantic.constr(min_length=1) or Field(..., min_length=1)) for the name and external_version fields in the FlowExistsBody class so validation fails early instead of passing empty strings to the DB lookup in database.flows.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/routers/openml/flows.py`:
- Around line 5-18: FlowExistsBody currently allows empty strings for name and
external_version because both are plain str; change the model to reject empty
values by specifying non-empty constraints (e.g., use
pydantic.constr(min_length=1) or Field(..., min_length=1)) for the name and
external_version fields in the FlowExistsBody class so validation fails early
instead of passing empty strings to the DB lookup in database.flows.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 21fd2185-be28-4cb4-ab90-ec25fd991100
📒 Files selected for processing (1)
src/routers/openml/flows.py
…cated wrapper
- Move FlowExistsBody to schemas/flows.py for reusability
- Keep GET /flows/exists/{name}/{version} as a deprecated thin wrapper
around POST /flows/exists for backward compatibility
- Update test imports accordingly
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/routers/openml/flows_test.py (1)
79-94: Good validation coverage; consider adding a test for URI-unsafe characters.The empty field validation test is well-structured. However, since the primary motivation for this PR is to support flow names with URI-unsafe characters (e.g.,
sklearn.ensemble.AdaBoostClassifier(base_estimator=sklearn.tree.DecisionTreeClassifier)), consider adding a test case that explicitly validates this scenario works correctly with the new POST endpoint.💡 Suggested test case for URI-unsafe flow names
def test_flow_exists_with_uri_unsafe_characters(py_api: TestClient, mocker: MockerFixture) -> None: """Verify POST endpoint handles flow names with URI-unsafe characters.""" unsafe_name = "sklearn.ensemble.AdaBoostClassifier(base_estimator=sklearn.tree.DecisionTreeClassifier)" # This would fail with the old GET endpoint due to URI encoding issues response = py_api.post( "/flows/exists", json={"name": unsafe_name, "external_version": "1.0"} ) # Expecting 404 since this flow doesn't exist in test data assert response.status_code == HTTPStatus.NOT_FOUND🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/routers/openml/flows_test.py` around lines 79 - 94, Add a new test function (e.g., test_flow_exists_with_uri_unsafe_characters) that posts to the "/flows/exists" endpoint using py_api with a URI-unsafe flow name such as "sklearn.ensemble.AdaBoostClassifier(base_estimator=sklearn.tree.DecisionTreeClassifier)" and external_version "1.0"; assert the response.status_code is HTTPStatus.NOT_FOUND (or the expected non-existent-flow status) to verify the POST endpoint accepts URI-unsafe characters in the request body rather than failing due to encoding.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/routers/openml/flows_test.py`:
- Around line 79-94: Add a new test function (e.g.,
test_flow_exists_with_uri_unsafe_characters) that posts to the "/flows/exists"
endpoint using py_api with a URI-unsafe flow name such as
"sklearn.ensemble.AdaBoostClassifier(base_estimator=sklearn.tree.DecisionTreeClassifier)"
and external_version "1.0"; assert the response.status_code is
HTTPStatus.NOT_FOUND (or the expected non-existent-flow status) to verify the
POST endpoint accepts URI-unsafe characters in the request body rather than
failing due to encoding.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 4a67d474-55b6-4840-93cd-34a66f961f6c
📒 Files selected for processing (3)
src/routers/openml/flows.pysrc/schemas/flows.pytests/routers/openml/flows_test.py
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/routers/openml/flows_test.py (1)
75-109: Consider adding tests for URI-unsafe characters and the deprecated GET endpoint.Given the PR's primary objective is to support URI-unsafe characters (e.g., sklearn flows with parentheses like
sklearn.pipeline.Pipeline(...)), adding an explicit integration test with such characters would validate the fix end-to-end.Additionally, there's no test coverage for the deprecated
GET /flows/exists/{name}/{external_version}endpoint to verify its delegation behavior works correctly.📝 Suggested test additions
# Test for URI-unsafe characters in POST (validates the fix) async def test_flow_exists_with_uri_unsafe_chars(flow: Flow, py_api: httpx.AsyncClient) -> None: """Verify that flow names with URI-unsafe characters work via POST.""" # This test would need a fixture flow with parentheses in its name name_with_parens = "sklearn.pipeline.Pipeline(steps=...)" response = await py_api.post( "/flows/exists", json={"name": name_with_parens, "external_version": "1.0"} ) # Expecting 404 since the flow doesn't exist, but importantly NOT a URI encoding error assert response.status_code == HTTPStatus.NOT_FOUND # Test for deprecated GET endpoint delegation async def test_flow_exists_get_deprecated(flow: Flow, py_api: httpx.AsyncClient) -> None: """Verify deprecated GET endpoint still works and delegates correctly.""" response = await py_api.get(f"/flows/exists/{flow.name}/{flow.external_version}") assert response.status_code == HTTPStatus.OK assert response.json() == {"flow_id": flow.id}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/routers/openml/flows_test.py` around lines 75 - 109, Add integration tests covering URI-unsafe characters and the deprecated GET endpoint: add a test similar to test_flow_exists_with_uri_unsafe_chars that posts to "/flows/exists" with a name containing parentheses (e.g., "sklearn.pipeline.Pipeline(...)") and asserts it returns HTTPStatus.NOT_FOUND (ensuring no URI-encoding failure), and add a test like test_flow_exists_get_deprecated that calls GET "/flows/exists/{name}/{external_version}" for an existing Flow fixture and asserts HTTPStatus.OK and the same JSON payload as test_flow_exists ({"flow_id": flow.id}) to verify delegation; place these alongside the existing tests (test_flow_exists, test_flow_exists_not_exists, test_flow_exists_rejects_empty_fields) so they run in the same suite.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/routers/openml/flows_test.py`:
- Around line 75-109: Add integration tests covering URI-unsafe characters and
the deprecated GET endpoint: add a test similar to
test_flow_exists_with_uri_unsafe_chars that posts to "/flows/exists" with a name
containing parentheses (e.g., "sklearn.pipeline.Pipeline(...)") and asserts it
returns HTTPStatus.NOT_FOUND (ensuring no URI-encoding failure), and add a test
like test_flow_exists_get_deprecated that calls GET
"/flows/exists/{name}/{external_version}" for an existing Flow fixture and
asserts HTTPStatus.OK and the same JSON payload as test_flow_exists ({"flow_id":
flow.id}) to verify delegation; place these alongside the existing tests
(test_flow_exists, test_flow_exists_not_exists,
test_flow_exists_rejects_empty_fields) so they run in the same suite.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 34e30bfa-cec0-4f31-8de3-cc7dc9b45ac1
📒 Files selected for processing (3)
src/routers/openml/flows.pytests/routers/openml/flows_test.pytests/routers/openml/migration/flows_migration_test.py
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/routers/openml/migration/flows_migration_test.py
Description:
Summary
GET /flows/exists/{name}/{external_version}endpointPOST /flows/existsaccepting{"name", "external_version"}in the request bodysklearn.ensemble.AdaBoostClassifier(base_estimator=sklearn.tree.DecisionTreeClassifier)) that were previously broken with the GET approachCloses #166
Test plan
POST /flows/existswith JSON bodyflow_id